<?php
if (!defined('__COLA_DIR__')) exit;

/**
 * 编辑文章组件
 *
 * @author edikud
 * @package Widget
 * @copyright Copyright (c) 2019 Cola (http://www.mcooo.com)
 * @license GNU General Public License 2.0
 */
class Widget_Contents_Post_Edit extends Widget_Abstract_Contents implements Widget_Interface_Do
{
    /**
     * 执行函数
     *
     * @throws Widget_Exception
     */
    public function execute()
    {
		/** 必须为贡献者以上权限 */
        $this->user->pass('contributor');
		
        /** 获取文章内容 */
        if (!empty($this->request->cid) && 'delete' != $this->request->do) {

            $this->select()
                ->where('table.contents.cid = ?', $this->request->cid)
                ->where('table.contents.type = ?', 'post')
			    ->limit(1)
			    ->fetchRow(array($this, 'push'));
	
            if (!$this->have()) {
                throw new Widget_Exception(_t('文章不存在'), 404);
            } else if ($this->have() && !$this->allow('edit')) {
                throw new Widget_Exception(_t('没有编辑权限'), 403);
            }
        }
    }
	
    /**
     * 获取当前时间
     *
     * @access protected
     * @return Date
     */
    protected function ___date()
    {
        return new Date();
    }

    /**
     * 获取页面偏移的URL Query
     *
     * @access protected
     * @param integer $created 创建时间
     * @param string $status 状态
     * @return string
     */
    protected function getPageOffsetQuery($cid)
    {
        return 'page=' . $this->getPageOffset('cid', $cid, 'post', 
		'on' == $this->request->all ? 0 : $this->user->uid);
    }
	
    /**
     * 生成表单
     *
     * @access public
     * @param string $action 表单动作
     * @return Form
     */
    public function form()
    {
        /** 构建表格 */
        $form = new Form($this->security->actionUrl('contents-post-edit', false));

        /** 标题 */
        $title = new Form_Text('title', NULL, NULL, _t('标题'));
        $form->addInput($title);
		
        /** 网址缩略名 */
        $alias = new Form_Text('alias', NULL, NULL, _t('网址缩略名'));
        $form->addInput($alias);

        /** 分类 */
        $options = array();
        $widgetMetas = $this->widget('Widget_Metas_Category_List');
        while ($widgetMetas->next()) {
            $options[$widgetMetas->mid] = str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;', $widgetMetas->level) . $widgetMetas->name;
        }
        $mids = new Form_Checkbox('mids', $options, 0, _t('分类'),
        _t('此文章将归档在您选择的分类下.'));
        $form->addInput($mids->multiMode());
		$mids->setAttr('style', 'padding:6px 0;max-height: 600px;width: 100%;overflow: auto;');

        /** 文章 */
        $text =  new Form_Textarea('text', NULL, NULL, _t('文章内容'));
        $form->addInput($text);
		$text->input->setAttr('style', 'min-height: 240px;');

        /** 文章 */
        $intro =  new Form_Textarea('intro', NULL, NULL, _t('摘要'));
        $form->addInput($intro);
		$intro->input->setAttr('style', 'min-height: 120px;');
		
        /** 标签 */
        $tags = new Form_Text('tags', NULL, NULL, _t('标签'), _t('逗号分隔, 最多支持5个'));
        $form->addInput($tags);

        /** 排序 */
        $order = new Form_Text('order', NULL, NULL, _t('排序'));
        $form->addInput($order);		
		
		/** 文章图标 */
        $pic = new Form_Text('pic', NULL, NULL, _t('文章图标'), '<label class="btn btn-light btn-sm cola-upload"><i class="fe fe-upload mr-2"></i><span>上传</span><input type="file" accept="image/*" name="file"></label>');
        $form->addInput($pic);

        $allowComment = new Form_Checkbox('allowComment', array('1'=>'允许评论'), 1, _t('评论权限'));
        $form->addInput($allowComment);

        /** 动作 */
        $do = new Form_Hidden('do');
        $form->set($do);

        /** 主键 */
        $cid = new Form_Hidden('cid');
        $form->addInput($cid);		
		
        /** 提交按钮 */
        $submit = new Form_Submit();
        $form->set($submit);
		
        if ($this->cid) {
			$tagNames = $this->tags ? implode(',', Common::arrayValues($this->tags, 'name')) : '';
			$tags->value($tagNames);
			$intro->value($this->intro);
			$order->value($this->order);
            $title->value($this->title);
            $alias->value($this->alias);
            $mids->value(explode(',', $this->mids));
			$text->value($this->text);
			$allowComment->value($this->allowComment);
            $do->value('update');
            $cid->value($this->cid);
            $pic->value($this->pic);
		    $pic->input->set($this->pic ? '<br><img style="margin: 5px 0;" class="cola-pic" src="'.$this->icon .'" />' : '', 'html');
            $submit->value(_t('更新文章'));

        } else {
            $do->value('insert');
            $submit->value(_t('发布文章'));
        }

		/** 默认上传js (可覆盖或修改) */
        $this->widget('Widget_Scripts')->set("
            (function () {
                $(document).ready(function () {
var jform = $(\"form\");					
jform.on('change', 'input[type=\"file\"]', function(e) {
	var jthis = $(this);
	var jdiv = jthis.parent().parent().parent();
	var jinput = jdiv.find('input[name=\"pic\"]');
	var cid = jform.find('input[name=\"cid\"]').val();//alert(cid);return;
    $.ajax({
		url: '".$this->security->actionUrl('upload', false)."',
        files: jthis,
        iframe: true,
		data: {id:cid, type:'post'},
		processData: false,
		dataType: 'text',
		cache:false,
		beforeSend: function(s){
			jdiv.find('.cola-upload span').html('正在上传...');
		},
		success: function(s){
		    s = (new Function(\"return \" + s))(); 
		    if(typeof s.code != 'undefined') {
			    if(s.code == 0) {
					if(!$('img', jdiv).length){
						jinput.after('<br><img style=\"margin: 5px 0;\" class=\"cola-pic\" src=\"".$this->options->uploadUrl ."' + s.data.filePath+'?'+Math.random() + '\"/>');
						
					}else{
						$('img', jdiv).attr('src', '".$this->options->uploadUrl ."' + s.data.filePath+'?'+Math.random());
					}
					jinput.val(s.data.filePath);
			    } else {
				   alert(s.msg);
			    }
		    } else {
			    alert(s);
		    }
		},
		complete: function(s){
			jdiv.find('.cola-upload span').html('上传');
		},
    });
});			

});
})();", 'post@upload');

		/** 插件接口 */
		//HOOK PLUG_Post_Form($form, $this);	

		return $form;

    }


    /**
     * 输出文章发布日期
     *
     * @access public
     * @param string $format 日期格式
     * @return void
     */
    public function date($format = NULL)
    {
        if (isset($this->created)) {
            parent::date($format);
        } else {
            echo date($format, $this->options->time + $this->options->timezone - $this->options->serverTimezone);
        }
    }

    /**
     * 获取文章权限
     *
     * @return bool
     */
    public function allow($permission)
    {
        if ('edit' == $permission) {
            $allow = ($this->user->pass('editor', true) || $this->uid == $this->user->uid);
        } else {
            $permission = 'allow' . ucfirst($permission);
            $allow = (isset($this->{$permission}) ? $this->{$permission} : false);
        }
        return $allow;
    }


    /**
     * 获取网页标题
     *
     * @access public
     * @return string
     */
    public function getMenuTitle()
    {
        if ($this->have()) {	
            return _t('编辑: %s', $this->title);
        } else {
            return _t('增加文章');
        }
    }

    /**
     * 发布文章
     *
     * @access public
     * @return void
     */
    public function insertPost($values = array())
    {
		// 发布插件接口
		//HOOK $values | PLUG_Post_Insert($values, $this);

        /** 发布一个新内容 */
        $insertId = $this->insert($values);

        if ($insertId > 0) {

            /** 更新内容数 */
		    !empty($values['uid']) && $this->db->update('table.users')
		        ->where('uid = ?', $values['uid'])
				->expression('contentsNum', 'contentsNum + 1')
				->affectedRows();
			
            /** 插入分类 */
            $this->setCategories($insertId, empty($values['mids']) ? '' : $values['mids']);
			
            /** 插入标签 */
            $this->setTags($insertId, empty($values['tags']) ? '' : $values['tags']);

            /** 同步附件 */
            list($images, $files) = $this->widget('Widget_Attachs_Edit')->sync('post', $insertId);
		    $this->update($insertId, array('imagesNum' => $images, 'filesNum' => $files));
			
			/** 压入数据 */
            $this->select()
			    ->where('table.contents.cid = ?', $insertId)
				->limit(1)
				->fetchRow(array($this, 'push'));

            // 完成发布插件接口
            //HOOK PLUG_Post_Insert_Success($this);

        }

		return $insertId;
    }
	
    public function updatePost($values = array())
    {
		if (!$this->have()) {
		    return ;
		}
		
		//HOOK $values | PLUG_Post_Update($values, $this);
		
		$cid = $this->cid;
		
        /** 插入分类 */
		$mids = empty($values['mids']) ? '' : $values['mids'];
        if($this->mids != $mids) { 
		    $this->setCategories($cid, $mids);
		}

        /** 插入标签 */
		$tags = empty($values['tags']) ? '' : $values['tags'];
		$tagNames = $this->tags ? implode(',', Common::arrayValues($this->tags, 'name')) : '';		
        if($tagNames != $tags) { 
		    $this->setTags($cid, $tags);
		}

        /** 同步附件 */
        list($images, $files) = $this->widget('Widget_Attachs_Edit')->sync('post', $cid);
		$values['images'] = $images;
		$values['files'] = $files;

        //HOOK $values | PLUG_Post_Update($values, $this);
		
        /** 更新数据 */
        $updateRows = $this->update($cid, $values);
		
		/** 压入数据 */
		$this->select()
		    ->where('table.contents.cid = ?', $cid)
			->limit(1)
			->fetchRow(array($this, 'push'));

        // 完成发布插件接口
        //HOOK PLUG_Post_Update_Success($this);
		
		return $updateRows;
    }
    /**
     * 删除文章
     *
     * @access public
     * @return void
     */
    public function deletePost($cid)
    {
        $deleteRows = false;

	    /** 压入数据 */
		$content = $this->db->select()
		    ->from('table.contents')
			->where('cid = ?', $cid)
			->fetchRow(array($this, 'push'));
			
        /** 插件接口 */
        //HOOK PLUG_Post_Delete($this);

        if ($this->isWriteable() && 'post' == $this->type) {

            /** 更新内容数 */
		    $this->db->update('table.users')
		        ->where('uid = ?', $content['uid'])
			    ->expression('contentsNum', 'contentsNum - 1')
				->affectedRows();
				
            /** 删除分类 */
            $this->setCategories($cid);

            /** 删除标签 */
            $this->setTags($cid);
			
			$Widget_Comments_Edit = $this->widget('Widget_Comments_Edit');
            while (1) {
                $arrlist = $this->db->select('coid')
				    ->from('table.comments')
			        ->where('cid = ?', $cid)
				    ->limit(1000)
				    ->fetchAll();
				
                if (empty($arrlist)) {
                    break;
                }
				
                foreach ($arrlist as $value) {
		            $Widget_Comments_Edit->deleteComment($value['coid']);
		        }
            }		

            /** 删除附件 */
            $this->widget('Widget_Attachs_Edit')->remove('post', $cid);
			
			/** 删除文章 */
			$deleteRows = $this->delete($cid);

            /** 插件接口 */
            //HOOK PLUG_Post_Delete_Success($this);

        }

		return $deleteRows;
    }
	
    public function operate($template = array())
    {
		$buttons = array();

		$buttons[] = Helper::element('a', _t('全选'), array(
		    'data-selectall'=>NULL,
			'href'=>'javascript:void(0);'
			)
		);

		$buttons[] = Helper::element('a', _t('删除'), array(
		    'href'=>'javascript:void(0);',
		    'data-action'=>$this->security->actionUrl('contents-post-edit?do=delete', false),
			'data-confirm'=>_t('删除不可恢复，确定删除？'),
			'data-item'=>'cid',
			'style'=>'color:red'
			)
		);

		/** 插件接口 */
		//HOOK $buttons[] | PLUG_Post_Operate($this);

		return $this->widget('Widget_Operate')->render($buttons);
    }

    /**
     * 设置内容标签
     *
     * @access public
     * @param integer $cid
     * @param string $newTags
     * @return void
     */
    public function setTags($cid, $newTags = NULL)
    {
		$widgetMetas  = $this->widget('Widget_Abstract_Metas');
		$insertTags = array();

		# 删除标签
		$tagsJson = $this->tagsJson ? Json::decode($this->tagsJson) : array();
	    foreach($tagsJson as $mid => $value)
		{
			$deleteRows = $this->db->delete('table.relate')
			    ->where('mid = ? AND cid = ?', $mid, $cid)
				->affectedRows();
			
            /** 更新内容数 */
		    $deleteRows && $this->db->update('table.metas')
		        ->where('mid = ?', $mid)
			    ->expression('contentsNum', 'contentsNum - 1')
				->affectedRows();
	    }

	    # 最多支持20个标签
	    if(is_string($newTags)) {
            $newTags = str_replace('，', ',', $newTags);
            $newTags = array_unique(array_map('trim', explode(',', $newTags)));
            $newTags = array_filter($newTags, array('Validate', 'xssCheck'));
	        $i=0;
	        foreach($newTags as $name)
			{
		        if (empty($name)) continue;
		        if ($i > 20) break;
		        $tagdata = $widgetMetas->getByName($name);
		        if(empty($tagdata)) {
			        $mid = $widgetMetas->insert(array('name'=>$name, 'type'=>'tag'));
					$tag = $this->db->select('alias')
					    ->from('table.metas')
						->where('mid = ?', $mid)
						->fetchRow();
				    $alias = $tag['alias'];
		        } else {
					$mid = $tagdata['mid'];
					$alias = $tagdata['alias'];
		        }
			    $insertTags[$mid] = array('alias'=>$alias, 'name'=>$name);
		        ++$i;
	        }
	    }

	    # 写入标签
	    foreach($insertTags as $mid => $value)
		{
			$select = $this->db->select(1)
			    ->from('table.relate')
				->where('mid = ? AND cid = ?', $mid, $cid)
				->fetchRow();
			if(!$select) {
				$insert = $this->db->insert('table.relate')
				    ->values(array('mid' => $mid, 'cid' => $cid))
					->affectedRows();

                /** 更新内容数 */
		        $insert && $this->db->update('table.metas')
		            ->where('mid = ?', $mid)
			        ->expression('contentsNum', 'contentsNum + 1')
				    ->affectedRows();
			}
	    }
		
		/** 增加或修改tag */
		if(NULL !== $newTags){
			$tagsJson = Json::encode($insertTags);
		    $this->update($cid, array('tagsJson' => $tagsJson));
		}
    }

    /**
     * 设置分类
     *
     * @access public
     * @param integer $cid 内容id
     * @param string $newMids 分类id的集合数组
     * @return void
     */
    public function setCategories($cid, $newMids = NULL)
    {
		$widgetCategory = $this->widget('Widget_Metas_Category_List');

		# 增加或修改分类
		if(NULL !== $newMids){
			$newMids = explode(',', $newMids);
		    $categories = $widgetCategory->getCategories();
		    $tmp = array();
		    # 过滤分类
		    foreach($newMids as $mid)
			{
			    isset($categories[$mid]) && $tmp[$mid] = $mid;
		    }

		    $newMids = $tmp ? $tmp : array(current($categories)['mid']);
		}

		# 删除旧分类
		if($this->mids){
			$deleteMids = array();
			$oldMids = explode(',', $this->mids);

            foreach ($oldMids as $mid)
			{
                # 分类所有上级
			    $parentsMids = $widgetCategory->getParentsMids($mid);
                foreach ($parentsMids as $mid)
				{
					$deleteMids[$mid] = $mid;
                }
		    }
            foreach ($deleteMids as $mid)
			{
                $delete = $this->db->delete('table.relate')
				    ->where('mid = ? AND cid = ?', $mid, $cid)
					->affectedRows();
					
                # 分类文章数减1
                $delete && $this->db->update('table.metas')
				    ->where('mid = ?', $mid)
					->expression('contentsNum', 'contentsNum - 1')
					->affectedRows();
            }
		}
		
		# 增加新分类
		if($newMids){
			$insertMids = array();
            foreach ($newMids as $mid)
			{
                # 分类所有上级
			    $parentsMids = $widgetCategory->getParentsMids($mid);
                foreach ($parentsMids as $mid)
				{
					$insertMids[$mid] = $mid;
                }
		    }
            foreach ($insertMids as $mid)
			{
				$select = $this->db->select(1)
				    ->from('table.relate')
					->where('mid = ? AND cid = ?', $mid, $cid)
					->fetchRow();
					
				if(!$select){
				    $insert = $this->db->insert('table.relate')->values(array('mid' => $mid, 'cid' => $cid))->affectedRows();
                    # 分类文章数加1
                    $insert && $this->db->update('table.metas')
				        ->where('mid = ?', $mid)
					    ->expression('contentsNum', 'contentsNum + 1')
					    ->affectedRows();
				}
            }
			$newMids = implode(',', $newMids);
			$this->update($cid, array('mids' => $newMids));
		}
    }
	
    /**
     * 绑定动作
     *
     * @access public
     * @return void
     */
    public function action()
    {
        $this->security->protect();
		
        switch ($this->request->do) {
            case 'insert':
                $contents = array(
				    'title'         =>  $this->request->get('title', _t('未命名文档')),
			        'uid'           =>  $this->user->uid,
					'type'          =>  'post',
                    'allowComment'  =>  !empty($this->request->getArray('allowComment')) ? 1 : 0,
                    'intro'         =>  $this->autoIntro($this->request->intro, $this->request->text),
					'mids'          =>  implode(',', $this->request->getArray('mids')),
					'tags'          =>  $this->request->get('tags', ''),
                );
                $contents += $this->request->from(array_keys($this->form()->getInputs()));

		        $this->insertPost($contents);
	
                /** 设置提示信息 */
                $this->result->set(0, _t('文章已经发布'), array('location'=>$this->options->ucenterUrl('posts?' . $this->getPageOffsetQuery($this->cid), false), 'cid'=>$this->theId));
				
            break;
            case 'update':
			
                $contents = array(
				    'title'         =>  $this->request->get('title', _t('未命名文档')),
			        'uid'           =>  $this->user->uid,
                    'allowComment'  =>  !empty($this->request->getArray('allowComment')) ? 1 : 0,
                    'intro'         =>  $this->autoIntro($this->request->intro, $this->request->text),
					'mids'          =>  implode(',', $this->request->getArray('mids')),
					'tags'          =>  $this->request->get('tags', ''),
                );
                $contents += $this->request->from(array_keys($this->form()->getInputs()));
		        $this->updatePost($contents);
			
                /** 设置提示信息 */
                $this->result->set(0, _t('文章更新成功'), array('location'=>$this->options->ucenterUrl('posts?' . $this->getPageOffsetQuery($this->cid), false), 'cid'=>$this->theId));
				
            break;
            case 'delete':
			
                $cids = $this->request->filter('int')->getArray('cid');
                $deleteRows = array();
                foreach ($cids as $cid) {
		            if($this->deletePost($cid)){ 
					    $deleteRows[] = $cid;
					}
		        }
				
                /** 设置提示信息 */
                $this->result->set(
				    $deleteRows ? 0 : 1, 
				    $deleteRows ? _t('成功删除 %s 篇文章', count($deleteRows)) : _t('没有文章被删除'),
				    $deleteRows
				);
				
            break;
        }
		$this->result->set(404, _t('请求的资源不存在'));
    }
}

